using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using Spring.Data.NHibernate;
using NHibernate;
namespace Bamboo.Core.Data
{
    public class HibernateSearchQueryCallBack : IHibernateCallback
    {
        
        private long totalRecord;
        private int currentPage;
        private int pageSize;
        private IList<SearchCondition> searchConditionList;
        private string className;
        private string sortField;
        private SortDirection sortDirection;
        private string fieldSelect;
        private string leftOuterJoin;

        public string LeftOuterJoin
        {
            get { return leftOuterJoin; }
            set { leftOuterJoin = value; }
        }
	
        public string FieldSelect
        {
            get { return fieldSelect; }
            set { fieldSelect = value; }
        }
	
	
        public SortDirection SortDirection
        {
            get { return sortDirection; }
            set { sortDirection = value; }
        }

        public string SortField
        {
            get { return sortField; }
            set { sortField = value; }
        }

        public string ClassName
        {
            get { return className; }
            set { className = value; }
        }

        public IList<SearchCondition> SearchConditionList
        {
            get { return searchConditionList; }
            set { searchConditionList = value; }
        }

        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        public int CurrentPage
        {
            get { return currentPage; }
            set { currentPage = value; }
        }

        public long TotalRecord
        {
            get { return totalRecord; }
            set { totalRecord = value; }
        }

        public HibernateSearchQueryCallBack(string className, 
            string fieldSelect, IList<SearchCondition> searchConditionList, 
            string sortField, SortDirection sortDirection, 
            int pageSize, int currentPage)
        {
            this.fieldSelect = fieldSelect;
            this.searchConditionList = searchConditionList;
            this.className = className;
            this.sortField = sortField;
            this.sortDirection = sortDirection;
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public HibernateSearchQueryCallBack(string className,
            string fieldSelect, string leftOuterJoin, IList<SearchCondition> searchConditionList,
            string sortField, SortDirection sortDirection,
            int pageSize, int currentPage)
        {
            this.leftOuterJoin = leftOuterJoin;
            this.fieldSelect = fieldSelect;
            this.searchConditionList = searchConditionList;
            this.className = className;
            this.sortField = sortField;
            this.sortDirection = sortDirection;
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public HibernateSearchQueryCallBack(string className, 
                    IList<SearchCondition> searchConditionList, string sortField,
                    SortDirection sortDirection, int pageSize, int currentPage)
        {
            this.searchConditionList = searchConditionList;
            this.className = className;
            this.sortField = sortField;
            this.sortDirection = sortDirection;
            this.currentPage = currentPage;
            this.pageSize = pageSize;
        }

        public object DoInHibernate(NHibernate.ISession session)
        {
            //count number of item
            string countHQL = "select count(*) from " + className + " item ";
            if (leftOuterJoin != null && leftOuterJoin.Trim() != string.Empty)
            {
                countHQL += " " + leftOuterJoin + " ";
            }
            countHQL += " where 1=1 ";
            string conditionHQL = SearchQueryHelper.BuildSearchHQL(searchConditionList);
            if (conditionHQL != null)
            {
                countHQL += " and " + conditionHQL;
            }
            IQuery countQuery = session.CreateQuery(countHQL);
            SearchQueryHelper.SetupSearchQuery(searchConditionList, countQuery);
            object countResult = countQuery.UniqueResult();
            if (countResult != null)
            {
                totalRecord = long.Parse(countResult.ToString());
            }

            //return the result
            string hql = null;
            if (fieldSelect != null && fieldSelect.Trim() != string.Empty)
            {
                hql = "select " + fieldSelect + " from " + className + " item ";
                if (leftOuterJoin != null && leftOuterJoin.Trim() != string.Empty)
                {
                    hql += " " + leftOuterJoin + " ";
                }
                hql += " where 1=1 ";
                if (conditionHQL != null)
                {
                    hql += " and " + conditionHQL;
                }
            }
            else
            {
                hql = SearchQueryHelper.BuildFullSearchHQL(className, searchConditionList);
            }
            if (sortField != null)
            {
                hql += " order by item." + sortField + " ";
                switch (sortDirection)
                {
                    case SortDirection.ASCENDING:
                        hql += " asc ";
                        break;
                    case SortDirection.DESCENDING:
                        hql += " desc ";
                        break;
                    default:
                        break;
                }
            }
            IQuery query = session.CreateQuery(hql);
            SearchQueryHelper.SetupSearchQuery(searchConditionList, query);
            if (pageSize != -1 && currentPage != -1)
            {
                query.SetFirstResult(currentPage * pageSize);
                query.SetMaxResults(pageSize);
            }

            return query.List();
        }
        



        
    }
}
